﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

using ULog.Client.Utils;
using ULog.Dto;


namespace ULog.Client
{
    public  class ULogClient
    {
        private static Encoding apiEncoding = Encoding.UTF8;
        //api服务器地址
        private int m_platFormID;
        private string m_ServerUrl = "";
        public ULogClient(int platFormID,string serverUrl="http://api.banmachewu.com/ULog")
        {
            m_platFormID = platFormID;
            m_ServerUrl = serverUrl;
        }
        #region 错误接口
        /// <summary>
        /// 错误接口
        /// </summary>
        /// <param name="ex">异常信息</param>
        public void Error(Exception ex)
        {
            var oInfo = new ErrorLogRequest()
            {
                ErrorMessage = ex.Message,
                ErrorTrace = ex.StackTrace,
                ErrorSource = ex.Source
            };
            Error(oInfo);
        }
        /// <summary>
        /// 错误接口
        /// </summary>
        /// <param name="ex">异常信息</param>
        /// <param name="clientIP">客户端地址</param>
        /// <param name="requestUrl">请求地址</param>
        public void Error(Exception ex,string clientIP,string requestUrl)
        {
            var oInfo = new ErrorLogRequest()
            {
                ClientIP = clientIP,
                RequestUrl = requestUrl,
                ErrorMessage = ex.Message,
                ErrorTrace = ex.StackTrace,
                ErrorSource = ex.Source
            };
            Error(oInfo);
        }
        /// <summary>
        /// 错误接口
        /// </summary>
        /// <param name="ex">异常信息</param>
        /// <param name="clientIP">客户端地址</param>
        /// <param name="requestUrl">请求地址</param>
        /// <param name="requestMethod">请求方法(Get、Post)</param>
        public void Error(Exception ex, string clientIP, string requestUrl,string requestMethod)
        {
            var oInfo = new ErrorLogRequest()
            {
                ClientIP = clientIP,
                RequestUrl = requestUrl,
                RequestMethod = requestMethod,
                ErrorMessage = ex.Message,
                ErrorTrace = ex.StackTrace,
                ErrorSource = ex.Source
            };
            Error(oInfo);
        }
        /// <summary>
        /// 错误接口
        /// </summary>
        /// <param name="ex">异常信息</param>
        /// <param name="clientIP">客户端地址</param>
        /// <param name="requestUrl">请求地址</param>
        /// <param name="requestMethod">请求方法(Get、Post)</param>
        /// <param name="postData">请求数据</param>
        public void Error(Exception ex, string clientIP, string requestUrl, string requestMethod,string postData)
        {
            var oInfo = new ErrorLogRequest()
            {
                ClientIP = clientIP,
                RequestUrl = requestUrl,
                RequestMethod = requestMethod,
                PostData = postData,
                ErrorMessage = ex.Message,
                ErrorTrace = ex.StackTrace,
                ErrorSource = ex.Source
            };
            Error(oInfo);
        }
        /// <summary>
        /// 错误接口
        /// </summary>
        /// <param name="ex">异常信息</param>
        /// <param name="clientIP">客户端地址</param>
        /// <param name="requestUrl">请求地址</param>
        /// <param name="requestMethod">请求方法(Get、Post)</param>
        /// <param name="postData">请求数据</param>
        /// <param name="userID">用户ID</param>
        public void Error(Exception ex, string clientIP, string requestUrl, string requestMethod, string postData,long userID)
        {
            var oInfo = new ErrorLogRequest()
            {
                ClientIP = clientIP,
                RequestUrl = requestUrl,
                RequestMethod = requestMethod,
                PostData = postData,
                UserID = userID,
                ErrorMessage = ex.Message,
                ErrorTrace = ex.StackTrace,
                ErrorSource = ex.Source
            };
            Error(oInfo);
        }
        /// <summary>
        /// 错误接口
        /// </summary>
        /// <param name="oInfo"></param>
        public void Error(ErrorLogRequest oInfo)
        {
            if (oInfo.CreatedDate.IsNullDateTime())
            {
                oInfo.CreatedDate = DateTime.Now;
            }
            oInfo.PlatformID = this.m_platFormID;

            string szApi = m_ServerUrl + "/Log/Error";
            //请求参数
            //var szJosnParam = JsonConvert.SerializeObject(oInfo);
            string szJosnParam = oInfo.ToJSON();
            string szContent = "";
            var bReturn = RequestHelper.PostJsonToWebApi(szApi, szJosnParam, apiEncoding, out szContent);
        }

        #endregion

        #region 行为接口
        /// <summary>
        /// 行为接口
        /// </summary>
        /// <param name="oInfo"></param>
        public void Action(ActionLogRequest oInfo)
        {
            if (oInfo.CreatedDate.IsNullDateTime())
            {
                oInfo.CreatedDate = DateTime.Now;
            }
            oInfo.PlatformID = this.m_platFormID;
            string szApi = m_ServerUrl + "/Log/Action";
            //请求参数
            //var szJosnParam = JsonConvert.SerializeObject(oInfo);
            var szJosnParam = oInfo.ToJSON();
            string szContent = "";
            var bReturn = RequestHelper.PostJsonToWebApi(szApi, szJosnParam, apiEncoding, out szContent);

        }
        #endregion


        #region 操作日志接口

        /// <summary>
        /// 通用操作
        /// </summary>
        /// <param name="moduleName">模块名称</param>
        /// <param name="methodName">方法名称</param>
        /// <param name="targetId">操作对象ID</param>
        /// <param name="opContent">操作内容</param>
        /// <param name="OpUserID">操作人ID</param>
        /// <param name="OpUserName">操作人名称</param>
        public void Operate(string moduleName, string methodName, string targetId, string opContent, int OpUserID, string OpUserName)
        {
            var request = new BizLogRequest()
            {
                ModuleName = moduleName,
                MethodName = methodName,
                TargetID = targetId,
                OpContent = opContent,
                CreateDateTime = DateTime.Now,
                ClientIP = IPHelper.IPAddress,
                PageUrl = RequestHelper.GetRequestUrl(),
                ServerName = RequestHelper.GetServerName(),
                OpUserID = OpUserID,
                OpUserName = OpUserName
            };

            Operate(request);
        }
        /// <summary>
        /// 通用操作
        /// </summary>
        /// <param name="methodName">方法名称</param>
        /// <param name="opContent">操作内容</param>
        public void Operate(string methodName, string opContent)
        {
            var request = new BizLogRequest()
            {
                ModuleName = "",
                MethodName = methodName,
                TargetID = "",
                OpContent = opContent,
                CreateDateTime = DateTime.Now,
                ClientIP = IPHelper.IPAddress,
                PageUrl = RequestHelper.GetRequestUrl(),
                ServerName = RequestHelper.GetServerName(),
                OpUserID = 0,
                OpUserName = ""
            };

            Operate(request);
        }
        /// <summary>
        /// 通用操作
        /// </summary>
        /// <param name="methodName">方法名称</param>
        /// <param name="targetId">操作对象ID</param>
        /// <param name="opContent">操作内容</param>
        public void Operate(string methodName, string targetId, string opContent)
        {
            var request = new BizLogRequest()
            {
                ModuleName = "",
                MethodName = methodName,
                TargetID = targetId,
                OpContent = opContent,
                CreateDateTime = DateTime.Now,
                ClientIP = IPHelper.IPAddress,
                PageUrl = RequestHelper.GetRequestUrl(),
                ServerName = RequestHelper.GetServerName(),
                OpUserID = 0,
                OpUserName = ""
            };

            Operate(request);
        }

        /// <summary>
        /// 通用操作
        /// </summary>
        /// <param name="moduleName">模块名称</param>
        /// <param name="methodName">方法名称</param>
        /// <param name="targetId">操作对象ID</param>
        /// <param name="opContent">操作内容</param>
        public void Operate(string moduleName, string methodName, string targetId, string opContent)
        {
            var request = new BizLogRequest()
            {
                ModuleName = moduleName,
                MethodName = methodName,
                TargetID = targetId,
                OpContent = opContent,
                CreateDateTime = DateTime.Now,
                ClientIP = IPHelper.IPAddress,
                PageUrl = RequestHelper.GetRequestUrl(),
                ServerName = RequestHelper.GetServerName(),
                OpUserID = 0,
                OpUserName = ""
            };

            Operate(request);
        }

        public void AddOperate(string methodName, object newEntity, string targetId, int OpUserID, string OpUserName)
        {
            var opContent = GetObjectInfo(newEntity);
            var request = new BizLogRequest()
            {
                ModuleName = "",
                MethodName = methodName,
                TargetID = targetId,
                OpContent = opContent,
                CreateDateTime = DateTime.Now,
                ClientIP = IPHelper.IPAddress,
                PageUrl = RequestHelper.GetRequestUrl(),
                ServerName = RequestHelper.GetServerName(),
                OpUserID = OpUserID,
                OpUserName = OpUserName
            };
            Operate(request);
        }


        /// <summary>
        /// 添加操作
        /// </summary>
        /// <param name="moduleName">模块名称</param>
        /// <param name="methodName">方法名称</param>
        /// <param name="newEntity">实体信息</param>
        /// <param name="targetId">实体信息主键ID</param>
        /// <param name="OpUserID">操作人ID</param>
        /// <param name="OpUserName">操作人姓名</param>
        public void AddOperate(string moduleName, string methodName, object newEntity,string targetId, int OpUserID, string OpUserName)
        {
            var opContent = GetObjectInfo(newEntity);
            var request = new BizLogRequest()
            {
                ModuleName = moduleName,
                MethodName = methodName,
                TargetID = targetId,
                OpContent = opContent,
                CreateDateTime = DateTime.Now,
                ClientIP = IPHelper.IPAddress,
                PageUrl = RequestHelper.GetRequestUrl(),
                ServerName = RequestHelper.GetServerName(),
                OpUserID = OpUserID,
                OpUserName = OpUserName
            };
            Operate(request);
        }

        public void UpdateOperate( string methodName, object oldInfo, object newInfo, string targetID, int OpUserID, string OpUserName)
        {
            var opContent = GetObjectInfo(oldInfo, newInfo);
            var request = new BizLogRequest()
            {
                ModuleName = "",
                MethodName = methodName,
                TargetID = targetID,
                OpContent = opContent,
                OldDataValue = oldInfo.ToJSON(),
                NewDataValue = newInfo.ToJSON(),
                CreateDateTime = DateTime.Now,
                ClientIP = IPHelper.IPAddress,
                PageUrl = RequestHelper.GetRequestUrl(),
                ServerName = RequestHelper.GetServerName(),
                OpUserID = OpUserID,
                OpUserName = OpUserName
            };
            Operate(request);
        }

        /// <summary>
        /// 修改操作
        /// </summary>
        /// <param name="moduleName">模块名称</param>
        /// <param name="methodName">方法名称</param>
        /// <param name="oldInfo">旧实体信息</param>
        /// <param name="newInfo">新实体信息</param>
        /// <param name="targetID">操作实体主键</param>
        /// <param name="OpUserID">操作人ID</param>
        /// <param name="OpUserName">操作人姓名</param>
        public void UpdateOperate(string moduleName, string methodName, object oldInfo, object newInfo,string targetID, int OpUserID, string OpUserName)
        {
            var opContent = GetObjectInfo(oldInfo,newInfo);
            var request = new BizLogRequest()
            {
                ModuleName = moduleName,
                MethodName = methodName,
                TargetID = targetID,
                OpContent = opContent,
                OldDataValue = oldInfo.ToJSON(),
                NewDataValue = newInfo.ToJSON(),
                CreateDateTime = DateTime.Now,
                ClientIP = IPHelper.IPAddress,
                PageUrl = RequestHelper.GetRequestUrl(),
                ServerName = RequestHelper.GetServerName(),
                OpUserID = OpUserID,
                OpUserName = OpUserName
            };
            Operate(request);
        }

        /// <summary>
        /// 删除操作
        /// </summary>
        /// <param name="moduleName">模块名称</param>
        /// <param name="methodName">方法名称</param>
        /// <param name="oInfo">实体信息</param>
        /// <param name="targetID">实体信息主键ID</param>
        /// <param name="OpUserID">操作人ID</param>
        /// <param name="OpUserName">操作人姓名</param>
        public void DeleteOperate(string methodName, object oInfo, string targetID, int OpUserID, string OpUserName)
        {
            var opContent = "删除操作：" + oInfo.ToJSON();
            var request = new BizLogRequest()
            {
                ModuleName = "",
                MethodName = methodName,
                TargetID = targetID,
                OpContent = opContent,
                CreateDateTime = DateTime.Now,
                ClientIP = IPHelper.IPAddress,
                PageUrl = RequestHelper.GetRequestUrl(),
                ServerName = RequestHelper.GetServerName(),
                OpUserID = OpUserID,
                OpUserName = OpUserName
            };
            Operate(request);
        }
        public void DeleteOperate(string moduleName, string methodName, object oInfo,string targetID, int OpUserID, string OpUserName)
        {
            var opContent = "删除操作："+oInfo.ToJSON();
            var request = new BizLogRequest()
            {
                ModuleName = moduleName,
                MethodName = methodName,
                TargetID = targetID,
                OpContent = opContent,
                CreateDateTime = DateTime.Now,
                ClientIP = IPHelper.IPAddress,
                PageUrl = RequestHelper.GetRequestUrl(),
                ServerName = RequestHelper.GetServerName(),
                OpUserID = OpUserID,
                OpUserName = OpUserName
            };
            Operate(request);
        }
        /// <summary>
        /// 操作日志接口
        /// </summary>
        /// <param name="oInfo"></param>
        public void Operate(BizLogRequest oInfo)
        {
            if (oInfo.CreateDateTime.IsNullDateTime())
            {
                oInfo.CreateDateTime = DateTime.Now;
            }
            oInfo.PlatformID = this.m_platFormID;
            string szApi = m_ServerUrl + "/Log/Operate";
            //请求参数
            /*var szJosnParam = JsonConvert.SerializeObject(oInfo)*/;
            var szJosnParam = oInfo.ToJSON();
            string szContent = "";
            var bReturn = RequestHelper.PostJsonToWebApi(szApi, szJosnParam, apiEncoding, out szContent);
        }
        private static string GetObjectInfo(object oldInfo, object newInfo)
        {
            StringBuilder sb = new StringBuilder();
            Type Objoldinfo = oldInfo.GetType();
            //需要改变的客户信息
            Type Objnewinfo = newInfo.GetType();

            PropertyInfo[] finfo_oldlist = Objoldinfo.GetProperties(BindingFlags.Public | BindingFlags.Instance);
            PropertyInfo[] finfo_newlist = Objoldinfo.GetProperties(BindingFlags.Public | BindingFlags.Instance);

            int intLength = finfo_oldlist.Length;

            for (int i = 0; i < intLength; i++)
            {
                if (finfo_oldlist[i].GetValue(oldInfo, null) != null && finfo_newlist[i].GetValue(newInfo, null) != null)
                {

                    if (!finfo_oldlist[i].GetValue(oldInfo, null).Equals(finfo_newlist[i].GetValue(newInfo, null)))
                    {
                        object[] objs = finfo_oldlist[i].GetCustomAttributes(typeof(DescriptionAttribute), true);
                        string des = "";
                        if (objs.Length > 0)
                        {
                            des = ((DescriptionAttribute)objs[0]).Description;
                        }
                        string proValue = "";
                        object objPropertyValue = finfo_newlist[i].GetValue(oldInfo, null);
                        if (objPropertyValue != null)
                        {
                            proValue = objPropertyValue.ToString();
                        }

                        string newValue = "";
                        object objnewPropertyValue = finfo_newlist[i].GetValue(newInfo, null);
                        if (objnewPropertyValue != null)
                        {
                            newValue = objnewPropertyValue.ToString();
                        }
                        sb.AppendFormat("修改了 <strong>{0}</strong>({1}):原数据“{2}”,修改为“{3}”<br>", des, finfo_oldlist[i].Name.ToString(), proValue, newValue);
                    }

                }

            }
            if (sb.ToString() != "")
            {
                return string.Format("<strong>{0}</strong><br>{1}", Objnewinfo.Name, sb.ToString());
            }
            return "";
        }

        private static string GetObjectInfo(object obj)
        {
            Type objinfo = obj.GetType();
            PropertyInfo[] peroperties = objinfo.GetProperties(BindingFlags.Public | BindingFlags.Instance);
            StringBuilder sb = new StringBuilder();
            foreach (PropertyInfo property in peroperties)
            {
                object[] objs = property.GetCustomAttributes(typeof(DescriptionAttribute), true);
                string des = "";
                if (objs.Length > 0)
                {
                    des = ((DescriptionAttribute)objs[0]).Description;
                }
                string proValue = "";
                object objPropertyValue = property.GetValue(obj, null);
                if (objPropertyValue != null)
                {
                    proValue = objPropertyValue.ToString();
                }
                string proName = property.Name.ToString();
                sb.AppendFormat("创建了 <strong>{0}</strong>({1}):“{2}”<br>", des, property.Name.ToString(), proValue);
            }
            if (sb.ToString() != "")
            {
                return string.Format("<strong>{0}</strong><br>{1}", objinfo.Name, sb.ToString());
            }
            return sb.ToString();
        }
        #endregion



    }
}
